﻿using System;
using System.Collections.Generic;
using Sustainalytics.DataLayer;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities.Governance;
using Sustainalytics.Governance.BusinessLogic.Helpers;
using Sustainalytics.Utils.Configuration;
using Sustainalytics.AwsS3.Client;
using System.Configuration;
using System.IO;

namespace Sustainalytics.Governance.BusinessLogic.PdfMetadata
{
    public class GovernancePdfMetadataManager : IGovernancePdfMetadataManager
    {
        private IGovernancePdfProfileMetadataRepository _governancePdfProfileMetadataRepository;
        private readonly IRepositoryCollection<GovernanceInsightInputFile> _governanceInputFileRepositoryWithFiles;
        private readonly IFileRepository _fileRepository;
        private readonly MongoGridFSHelper mongoGridFSHelper;
        private string _baseUrl;

        private readonly string _bucketName;

        public IGovernancePdfProfileMetadataRepository GovernancePdfProfileMetadataRepository { get => _governancePdfProfileMetadataRepository; set => _governancePdfProfileMetadataRepository = value; }

        public GovernancePdfMetadataManager(IGovernancePdfProfileMetadataRepository governancePdfProfileMetadataRepository,
                                            IRepositoryCollection<GovernanceInsightInputFile> governanceInputFileRepositoryWithFiles,
                                            string baseUrl)
        {
            _governancePdfProfileMetadataRepository = governancePdfProfileMetadataRepository;
            _governanceInputFileRepositoryWithFiles = governanceInputFileRepositoryWithFiles;
            _baseUrl = baseUrl;
            mongoGridFSHelper = governancePdfProfileMetadataRepository.GetMongoGridFSHelper();
            _bucketName = SettingsHelper.Read("s3-governance-reports", "dev-globalaccess-europe/GovernanceReports");
            var connectionString = ConfigurationManager.ConnectionStrings["GovernanceInputFile"].ConnectionString;
            _fileRepository = new FileRepository(connectionString);
        }

        public bool UpdateGovernancePdfProfileMetadata(GovernancePdfProfileMetadataDto pdfProfile, string userName)
        {
            bool ret;
            //extract to private method
            var existingPdf = _governancePdfProfileMetadataRepository.GetFileMetadata(Guid.Parse(pdfProfile.CompanyId), pdfProfile.GovernancePdfType);

            if (existingPdf != null)
            {
                _governanceInputFileRepositoryWithFiles.Delete(existingPdf.FileId);
                
                existingPdf.OperationType = UpdateOperationType.Updated;
                existingPdf.LastOperationDateTime = DateTime.UtcNow;
                //existingPdf.FileId = Guid.Parse(pdfProfile.FileId);
                existingPdf.LastOperationUserName = userName;
                ret = _governancePdfProfileMetadataRepository.CreateOrUpdate(existingPdf);
            }
            else
            {
                ret = _governancePdfProfileMetadataRepository.CreateOrUpdate(new GovernancePdfProfileMetadata()
                {
                    Id = Guid.NewGuid(),
                    //FileId = Guid.Parse(pdfProfile.FileId),
                    LastOperationDateTime = DateTime.UtcNow,
                    OperationType = pdfProfile.UpdateOperationType,
                    GovernancePdfType = pdfProfile.GovernancePdfType,
                    LastOperationUserName = userName,
                    FileName = pdfProfile.FileName,
                    CompanyId = Guid.Parse(pdfProfile.CompanyId),
                });
            }
            return ret;
        }

        public bool ExportAllReportsToS3(GovernancePdfType governancePdfType)
        {
            List<GovernancePdfProfileMetadata> allItems = _governancePdfProfileMetadataRepository.GetAllProfileMetadata();
            var allProfileMetadata = allItems.FindAll(x => governancePdfType == GovernancePdfType.All || x.GovernancePdfType == governancePdfType);
            byte[] fileContentByteArray;
            foreach (GovernancePdfProfileMetadata profile in allProfileMetadata)
            {
                if (profile.FileId != Guid.Empty)
                {
                    var fileData = _fileRepository.GetDownloadStream(profile.FileId);
                    if (fileData != null)
                    {
                        try
                        {
                            using (var memoryStream = new MemoryStream())
                            {
                                fileData.Item1.CopyTo(memoryStream);
                                fileContentByteArray = memoryStream.ToArray();
                            }
                            this.SaveFileInS3(profile.CompanyId.ToString() + ".pdf", profile.GovernancePdfType.ToString(), fileContentByteArray);
                        }
                        catch (Exception ex) { }
                    }
                }
            }
            return true;
        }

        public bool SaveFileInS3(string fileName, string governancePdfType, byte[] fileContentByteArray)
        {
            bool isError = false;
            S3ClientSettings _s3ClientSettings;
            _s3ClientSettings = new S3ClientSettings
            {
                AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJKGZZMOFAVOVLHJA"),
                SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
            };

            using (var s3Client = new S3Client(_s3ClientSettings))
            {
                try
                {
                    var fullPath = string.Format("{0}/{1}", governancePdfType, fileName);
                    s3Client.UploadFile(_bucketName, fullPath, fileContentByteArray);
                }
                catch (Exception) { isError = true; }
            }
            return !isError;

        }

        public byte[] LoadFileFromS3(Guid companyId, string governancePdfType)
        {
            byte[] fileContentByteArray;
            S3ClientSettings _s3ClientSettings;
            _s3ClientSettings = new S3ClientSettings
            {
                AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJKGZZMOFAVOVLHJA"),
                SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
            };

            using (var s3Client = new S3Client(_s3ClientSettings))
            {
                var fullPath = string.Format("{0}/{1}", governancePdfType, companyId.ToString() + ".pdf");
                var stream = s3Client.GetFileStream(_bucketName, fullPath);
                using (var memoryStream = new MemoryStream())
                {
                    stream.CopyTo(memoryStream);
                    fileContentByteArray = memoryStream.ToArray();
                }
            }
            return fileContentByteArray;
        }

        public List<GovernancePdfProfileMetadataDto> GetProfileByCompany(Guid companyId, string hostUrl)
        {
            //read governance profile from governance repository
            var result = _governancePdfProfileMetadataRepository.ReadByCompanyId(companyId);

            var dtoResults = new List<GovernancePdfProfileMetadataDto>();
            result.ForEach(x =>
            {
                dtoResults.Add(new GovernancePdfProfileMetadataDto()
                {
                    Id = x.Id.ToString(),
                    FileId = x.FileId.ToString(),
                    CompanyId = x.CompanyId.ToString(),
                    LastOperationDate = x.LastOperationDateTime,
                    LastOperationUserName = x.LastOperationUserName,
                    UpdateOperationType = x.OperationType,
                    GovernancePdfType = x.GovernancePdfType,
                    CorporateGovernancePdfProfileString = x.GovernancePdfType.GetDisplayName(),
                    UpdateOperationTypeString = x.OperationType.GetDisplayName(),
                    FileName = x.FileName,
                    FileUrl = ComposeFileUrl.GetUrl(x.FileId, hostUrl, "api/v1/filesclientplatform/")
                });
            });

            return dtoResults;
        }

        public void DeletePdfMetadataFile(Guid companyId, GovernancePdfType governancePdfType = GovernancePdfType.BusinessAndFinancialProfile)
        {
            if (companyId == Guid.Empty)
                throw new ArgumentNullException("companyId");
            //get the file using fileId
            //update status file to deleted in GovernancePdfProfileMetadata using fileId
            var pdfProfile = _governancePdfProfileMetadataRepository.GetFileMetadata(companyId, governancePdfType);
            pdfProfile.OperationType = UpdateOperationType.Deleted;
            _governancePdfProfileMetadataRepository.CreateOrUpdate(pdfProfile);

            //delete file from fs.files
            //if (update)
            //    mongoGridFSHelper.DeleteFile(fileId);
        }

        public void DeletePdfInsightFile(Guid fileId)
        {
            if (fileId == Guid.Empty)
                throw new ArgumentNullException("fileId");
            //get the file using fileId
            //update status file to deleted in GovernancePdfProfileMetadata using fileId
            _governanceInputFileRepositoryWithFiles.DeleteWhere(x => x.FileId == fileId);
        }
    }
}
